home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / GNUPLOTdoc.lha / docs / doc2ms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-22  |  6.1 KB  |  295 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: doc2ms.c,v 1.8 1995/04/06 14:03:59 drd Exp $";
  3. #endif
  4.  
  5.  
  6. /*
  7.  * doc2ms.c  -- program to convert Gnuplot .DOC format to *roff -ms document
  8.  * From hlp2ms by Thomas Williams 
  9.  *
  10.  * Modified by Russell Lang, 2nd October 1989
  11.  * to make vms help level 1 and 2 create the same ms section level.
  12.  *
  13.  * Modified to become doc2ms by David Kotz (David.Kotz@Dartmouth.edu) 12/89
  14.  * Added table and backquote support.
  15.  *
  16.  * usage:  doc2ms [file.doc [file.ms]]
  17.  *
  18.  *   where file.doc is a VMS .DOC file, and file.ms will be a [nt]roff
  19.  *     document suitable for printing with nroff -ms or troff -ms
  20.  *
  21.  * typical usage for GNUPLOT:
  22.  *
  23.  *   doc2ms gnuplot.doc | tbl | eqn | troff -ms
  24.  *
  25.  * or
  26.  *
  27.  *   doc2ms gnuplot.doc | groff -ms -et >gnuplot.ps
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <ctype.h>
  32.  
  33. #include "ansichek.h"
  34.  
  35. #ifdef ANSI_C
  36. #include <stdlib.h>
  37. #endif
  38.  
  39. #define MAX_NAME_LEN    256
  40. #define MAX_LINE_LEN    256
  41. #define LINE_SKIP        3
  42.  
  43. #define TRUE 1
  44. #define FALSE 0
  45.  
  46. void main __P(( int argc, char **argv ));
  47. void init __P(( FILE *b ));
  48. void convert __P(( FILE *a, FILE *b ));
  49. void process_line __P(( char *line, FILE *b ));
  50. void section __P(( char *line, FILE *b ));
  51. void putms __P(( char *s, FILE *file ));
  52. void putms_verb __P(( char *s, FILE *file ));
  53. void finish __P(( FILE *b ));
  54.  
  55. typedef int boolean;
  56.  
  57. static boolean intable = FALSE;
  58.  
  59. void main(argc,argv)
  60. int argc;
  61. char **argv;
  62. {
  63. FILE * infile;
  64. FILE * outfile;
  65.     infile = stdin;
  66.     outfile = stdout;
  67.     if (argc > 3) {
  68.         fprintf(stderr,"Usage: %s [infile [outfile]]\n", argv[0]);
  69.         exit(1);
  70.     }
  71.     if (argc >= 2) 
  72.         if ( (infile = fopen(argv[1],"r")) == (FILE *)NULL) {
  73.             fprintf(stderr,"%s: Can't open %s for reading\n",
  74.                 argv[0], argv[1]);
  75.             exit(1);
  76.         }
  77.     if (argc == 3)
  78.         if ( (outfile = fopen(argv[2],"w")) == (FILE *)NULL) {
  79.             fprintf(stderr,"%s: Can't open %s for writing\n",
  80.                 argv[0], argv[2]);
  81.         }
  82.     
  83.     init(outfile);
  84.     convert(infile,outfile);
  85.     finish(outfile);
  86.     exit(0);
  87. }
  88.  
  89.  
  90. void init(b)
  91. FILE *b;
  92. {
  93.     /* in nroff, increase line length by 8 and don't adjust lines */
  94.     (void) fputs(".if n \\{.nr LL +8m\n.na \\}\n",b);
  95.     (void) fputs(".nr PO +0.3i\n",b);
  96.     (void) fputs(".so titlepag.ms\n",b);
  97.     (void) fputs(".pn 1\n",b);
  98.     (void) fputs(".bp\n",b);
  99.     (void) fputs(".ta 1.5i 3.0i 4.5i 6.0i 7.5i\n",b);
  100.     (void) fputs("\\&\n.sp 3\n.PP\n",b);
  101.     /* following line commented out by rjl
  102.     (void) fputs(".so intro\n",b);
  103.     */
  104. }
  105.  
  106.  
  107. void convert(a,b)
  108.     FILE *a,*b;
  109. {
  110.     static char line[MAX_LINE_LEN];
  111.  
  112.     while (fgets(line,MAX_LINE_LEN,a)) {
  113.        process_line(line, b);
  114.     }
  115. }
  116.  
  117. void process_line(line, b)
  118.     char *line;
  119.     FILE *b;
  120. {
  121.     switch(line[0]) {        /* control character */
  122.        case '?': {            /* interactive help entry */
  123.           break;            /* ignore */
  124.        }
  125.        case '@': {            /* start/end table */
  126.           if (intable) {
  127.              (void) fputs(".TE\n.KE\n", b);
  128.              (void) fputs(".EQ\ndelim off\n.EN\n\n",b);
  129.              intable = FALSE;
  130.           } else {
  131.              (void) fputs("\n.EQ\ndelim $$\n.EN\n",b);
  132.              (void) fputs(".KS\n.TS\ncenter box tab (@) ;\n", b);
  133.              (void) fputs("c c l .\n", b);
  134.              intable = TRUE;
  135.           }
  136.           /* ignore rest of line */
  137.           break;
  138.        }
  139.        case '^': {            /* html table entry */
  140.           break;            /* ignore */
  141.        }
  142.        case '#': {            /* latex table entry */
  143.           break;            /* ignore */
  144.        }
  145.        case '%': {            /* troff table entry */
  146.           if (intable)
  147.             (void) fputs(line+1, b); /* copy directly */
  148.           else
  149.             fprintf(stderr, "error: %% line found outside of table\n");
  150.           break;
  151.        }
  152.        case '\n':            /* empty text line */
  153.        case ' ': {            /* normal text line */
  154.           if (intable)
  155.             break;        /* ignore while in table */
  156.           switch(line[1]) {
  157.              case ' ': {
  158.                 /* verbatim mode */
  159.                 fputs(".br\n",b); 
  160.                 putms_verb(line+1,b); 
  161.                 fputs(".br\n",b);
  162.                 break;
  163.              }
  164.              case '\'': {
  165.                 fputs("\\&",b);
  166.                 putms(line+1,b); 
  167.                 break;
  168.              }
  169.              default: {
  170.                 if (line[0] == '\n')
  171.                   putms(line,b); /* handle totally blank line */
  172.                 else
  173.                   putms(line+1,b);
  174.                 break;
  175.              }
  176.              break;
  177.           }
  178.           break;
  179.        }
  180.        default: {
  181.           if (isdigit(line[0])) { /* start of section */
  182.              if (!intable)    /* ignore while in table */
  183.                section(line, b);
  184.           } else
  185.             fprintf(stderr, "unknown control code '%c' in column 1\n", 
  186.                   line[0]);
  187.           break;
  188.        }
  189.     }
  190. }
  191.  
  192.  
  193. /* process a line with a digit control char */
  194. /* starts a new [sub]section */
  195.  
  196. void section(line, b)
  197.     char *line;
  198.     FILE *b;
  199. {
  200.     static char string[MAX_LINE_LEN];
  201.     int sh_i;
  202.     static int old = 1;
  203.  
  204.   
  205.     (void) sscanf(line,"%d %[^\n]s",&sh_i,string);
  206.     
  207.     (void) fprintf(b,".sp %d\n",(sh_i == 1) ? LINE_SKIP : LINE_SKIP-1);
  208.     
  209.     if (sh_i > old) {
  210.        do
  211.         if (old!=1)    /* this line added by rjl */
  212.           (void) fputs(".RS\n.IP\n",b);
  213.        while (++old < sh_i);
  214.     }
  215.     else if (sh_i < old) {
  216.        do
  217.                if (sh_i!=1) /* this line added by rjl */
  218.                 (void) fputs(".RE\n.br\n",b);
  219.        while (--old > sh_i);
  220.     }
  221.     
  222.     /* added by dfk to capitalize section headers */
  223.     if (islower(string[0]))
  224.      string[0] = toupper(string[0]);
  225.     
  226.     /* next 3 lines added by rjl */
  227.     if (sh_i!=1) 
  228.      (void) fprintf(b,".NH %d\n%s\n.sp 1\n.LP\n",sh_i-1,string);
  229.     else 
  230.      (void) fprintf(b,".NH %d\n%s\n.sp 1\n.LP\n",sh_i,string);
  231.     old = sh_i;
  232.     
  233.     (void) fputs(".XS\n",b);
  234.     (void) fputs(string,b);
  235.     (void) fputs("\n.XE\n",b);
  236. }
  237.  
  238. void putms(s, file)
  239.     char *s;
  240.     FILE *file;
  241. {
  242.     static boolean inquote = FALSE;
  243.  
  244.     while (*s != '\0') {
  245.        switch (*s) {
  246.           case '`': {        /* backquote -> boldface */
  247.              if (inquote) {
  248.                 fputs("\\fR", file);
  249.                 inquote = FALSE;
  250.              } else {
  251.                 fputs("\\fB", file);
  252.                 inquote = TRUE;
  253.              }
  254.              break;
  255.           }
  256.           case '\\': {        /* backslash */
  257.              fputs("\\\\", file);
  258.              break;
  259.           }
  260.           default: {
  261.              fputc(*s, file);
  262.              break;
  263.           }
  264.        }
  265.        s++;
  266.     }
  267. }
  268.  
  269. /*
  270.  * convert a verbatim line to troff input style, i.e. convert "\" to "\\"
  271.  * (added by Alexander Lehmann 01/30/93)
  272.  */
  273.  
  274. void putms_verb(s, file)
  275.     char *s;
  276.     FILE *file;
  277. {
  278.     while (*s != '\0') {
  279.        if (*s == '\\') {
  280.          fputc('\\', file);
  281.        }
  282.        fputc(*s, file);
  283.        s++;
  284.     }
  285. }
  286.  
  287. void finish(b)        /* spit out table of contents */
  288. FILE *b;
  289. {
  290.     (void) fputs(".pn 1\n",b);
  291.     (void) fputs(".ds RH %\n",b);
  292.     (void) fputs(".af % i\n",b);
  293.     (void) fputs(".bp\n.PX\n",b);
  294. }
  295.